/*
 * Copyright (c) 2010, German Buela
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * The name of German Buela may not be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY GERMAN BUELA "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL GERMAN BUELA BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.gbuela.swt

import org.eclipse.swt.SWT
import org.eclipse.swt.widgets.Layout
import org.eclipse.swt.widgets.Composite
import org.eclipse.swt.custom.ScrolledComposite
import org.eclipse.swt.widgets.Button
import org.eclipse.swt.layout._
import org.eclipse.swt.events._


trait SwtHelper {
  implicit def varargs2list(args: SwtElem *):List[SwtElem] = List(args:_*)
  def hangFrom(root: Composite)(comp:SwtComp) = { }
  def label(text:String): SwtLabel = new SwtLabel(text, None)
  def label(text:String, handler: => Unit) = new SwtEventLabel(text, None, handler)
  def label(text:String, fontSize: Int, handler: => Unit) = new SwtEventLabel(text, Some(fontSize), handler)
  def label(text:String, fontSize: Int): SwtLabel = new SwtLabel(text, Some(fontSize))
  def checkbox(text:String):SwtCheckbox = new SwtCheckbox(text)
  def vertical = new SwtComp(SWTLayout().row.vert)
  def horizontal = new SwtComp(SWTLayout().row.horiz)
  def horizontalWrap = new SwtComp(SWTLayout().row.horiz.withWrap)
  def fill = new SwtComp(SWTLayout().fill)
  def image(filename:String) = new SwtImageBuilder(filename)
}

trait SwtElem { 
  def hangFrom(parent: Composite): this.type
}

class SwtComp(val layout:SWTLayout) extends SwtElem {
    protected var children: List[SwtElem] = Nil
    var comp:Composite = null
    var layoutData:RowData = null

    def apply(children:  SwtElem *): SwtComp= apply(List(children:_*))
    def apply(children: List[SwtElem]): SwtComp = { this.children = children; this }
    
    def hangFrom(parent:Composite) = {
      comp = new Composite(parent, SWT.NONE)
      if(layoutData != null) comp.setLayoutData(layoutData)
      comp.setLayout(layout.get)
      for(val elem <- children) {
        elem hangFrom comp
      }
      this
    }
    
    def withRowData(width:Int, height:Int): SwtComp = {
      layoutData = new RowData(width,height)
      this
    }
}

trait SwtControl extends SwtElem 

class SwtLabel(val text:String, val fontSize:Option[Int]) extends SwtControl  {
  def hangFrom(parent: Composite) =  {SWT_Label(parent, text, fontSize);this}
}

class SwtEventLabel(val text:String, val fontSize:Option[Int], clickHandler: => Unit) extends SwtControl {
  def hangFrom(parent:Composite) = { new HLabel(parent, text, clickHandler); this }
}

class SwtCheckbox(val text:String) extends SwtControl {
  private var chkbox: Button = null
  private var ch: Option[Boolean => Unit] = None
    
  def hangFrom(parent: Composite) =  { 
    chkbox = new Button(parent, SWT.CHECK)
    chkbox.setText(text)
    if(ch.isDefined) {
      chkbox.addSelectionListener(new SelectionListener() { 
        override def widgetSelected(evt: SelectionEvent) = ch.get(chkbox.getSelection) 
        override def widgetDefaultSelected(evt: SelectionEvent) = {}
      })
    }
    this 
  }
  def isChecked = if(chkbox == null) false else chkbox.getSelection
  def setChecked(checked: Boolean) = chkbox.setSelection(checked)
  
  def onClick(clickHandler: Boolean => Unit) = {
    this.ch = Some( clickHandler )
    this
  }
}
class SwtImageBuilder(val fileName:String) extends SwtControl {
  private var scale:Option[(Int,Int)] = None
  private var pos:Option[(Int,Int)] = None
  private var ch: Option[() => Unit] = None
  private var hoverFileName: Option[String] = None
  private var clickFileName: Option[String] = None
  private var tooltip: Option[String] = None
  
  def scaleTo(width:Int, height:Int) = {
    this.scale = Some((width,height))
    this
  }
  def at(x:Int, y:Int) = {
    this.pos = Some((x,y))
    this
  }
  def onClick(clickHandler: => Unit) = {
    this.ch = Some({ () => clickHandler })
    this
  }
  def hover(fn: String) = {
    this.hoverFileName = if(fn==null) None else Some(fn)
    this
  }
  def click(fn: String) = {
    this.clickFileName = if(fn==null) None else Some(fn)
    this
  }
  def withTooltip(tt: String) = {
    this.tooltip = if(tt == null) None else Some(tt)
    this
  }
  
  def hangFrom(container:Composite) = {new SwtImage(container, fileName, hoverFileName, clickFileName, scale, pos, tooltip, ch ) ;this}
}
